package com.yungu.swift.assets.driver.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yungu.swift.assets.config.ApplicationConfig;
import com.yungu.swift.assets.driver.dao.DriverFaceRecognitionMapper;
import com.yungu.swift.assets.driver.dao.DriverMapper;
import com.yungu.swift.assets.driver.model.dto.DriverDto;
import com.yungu.swift.assets.driver.model.dto.DriverFaceRecognitionDto;
import com.yungu.swift.assets.driver.service.DriverFaceRecognitionService;
import com.yungu.swift.assets.utils.FaceRecognitionUtils;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.mapper.IMapper;
import com.yungu.swift.base.model.config.DriverConfig;
import com.yungu.swift.base.service.impl.BaseServiceImpl;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.DriverConstant;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.ParamUtil;
import com.yungu.swift.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.yungu.swift.assets.config.NacosListener.SYS_CONFIG;
import static com.yungu.swift.assets.driver.enums.DriverErrorEnum.*;

/**
 * Copyright © 厦门千夏软件科技有限公司 2016-2017 All Right Reserved
 * <p>
 * 司机人脸识别记录表
 *
 * @author Mojo - Generate
 * @version 1.0.2-RELEASE
 * @since 2018-12-20 15:02:46
 */

@Service
public class DriverFaceRecognitionServiceImpl extends BaseServiceImpl<DriverFaceRecognitionDto>
        implements DriverFaceRecognitionService {
    @Autowired
    private DriverFaceRecognitionMapper driverFaceRecognitionMapper;
    @Autowired
    private DriverMapper driverMapper;

    /**
     * 第一次人脸识别
     */
    public final static int IS_FIRST_FACE_RECOGNITION = 1;
    /**
     * 是否人脸识别成功 1成功
     */
    public final static int FACE_RECOGNITION_SUCCESS = 1;


    @Override
    protected IMapper<DriverFaceRecognitionDto> getMapper() {
        return driverFaceRecognitionMapper;
    }

    /**
     * 人脸识别校验
     *
     * @param paraMap
     * @return
     */
    @Override
    public ResponseData<Map<String, Object>> checkCertification(Map<String, Object> paraMap) {
        Map<String, Object> resultMap = MapUtils.build();
        String mobile = String.valueOf(paraMap.get("mobile"));
        //查询司机信息 获取司机身份证照片
        DriverDto driverDto = getDriver(mobile);
        if (driverDto == null) {
            return ResponseData.buildErrorResponse(DRIVER_NOT_FIND.getCode(), DRIVER_NOT_FIND.getMsg());
        }
        //检查是否对应业务的司机是否开启人脸识别开关以及人脸识别过期时间
        String scene = String.valueOf(paraMap.get("scene"));
        DriverConfig.CommonBean.FaceRecognitionBean.FaceBean faceBean = getFaceRecognitionInfo(driverDto.getBusinessType());
        Boolean trunOn = true;
        switch (scene) {
            case "LOGINS_FACE":
                trunOn = faceBean.getLogin();
                break;
            case "DEPART_FACE":
                trunOn = faceBean.getDepart();
                break;
            case "PASSWORD_FACE":
                trunOn = faceBean.getResetPassword();
                break;
            default:
                break;
        }
        if (!trunOn) {
            return ResponseData.buildErrorResponse(FACE_RECOGNITION_NOT_OPEN.getCode(), FACE_RECOGNITION_NOT_OPEN.getMsg());
        }
        Integer failureTime = ParamUtil.defaultIfNull(faceBean.getDuration(), 0);
        //判断是否需要人脸识别
        //成功状态
        paraMap.put("status", FACE_RECOGNITION_SUCCESS);
        DriverFaceRecognitionDto driverFaceRecognitionEntity = driverFaceRecognitionMapper.getNewWestRecode(paraMap);
        //未查到成功的认证记录 判断为第一次认证 使用RPBioOnly方案 并生成一条认证记录
        if (driverFaceRecognitionEntity == null) {
            //构造司机姓名身份证等信息作为获取认证token参数
            String driverName = driverDto.getName();
            String driverIdCareNo = driverDto.getIdCard();
            if (driverName == null || driverIdCareNo == null) {
                return ResponseData.buildErrorResponse(FACE_RECOGNITION_DRIVER_ERROR.getCode(), FACE_RECOGNITION_DRIVER_ERROR.getMsg());
            }
            //构造binding
            String binding = buildBinding(driverDto);
            String ticketId = StringUtils.buildUUID();
            //获取认证token
            driverFaceRecognitionEntity = FaceRecognitionUtils.rPBioOnly(ticketId, binding);
            if (driverFaceRecognitionEntity.getToken() == null) {
                return ResponseData.buildErrorResponse(FACE_RECOGNITION_TOKEN_EXCEPTION.getCode(), FACE_RECOGNITION_TOKEN_EXCEPTION.getMsg());
            }
            //新增认证记录
            driverFaceRecognitionEntity.setMobile(mobile);
            driverFaceRecognitionEntity.setDriverUuid(driverDto.getUuid());
            driverFaceRecognitionEntity.setIsFirst(IS_FIRST_FACE_RECOGNITION);
            driverFaceRecognitionMapper.add(driverFaceRecognitionEntity);
        } else {
            //失效时间 分钟
            //已经存在认证记录，判断后台设置的失效时间 若认证失效 需要重新认证
            if (failureTime == 0 || (System.currentTimeMillis() -
                    driverFaceRecognitionEntity.getCertificationTime().getTime()) / (1000 * 60) < failureTime) {
                return ResponseData.buildErrorResponse(FACE_RECOGNITION_NO_CERTIFICATION.getCode(), FACE_RECOGNITION_NO_CERTIFICATION.getMsg());
            }
            //已经首次认证通过 使用FVBioOnly方案 获取上一次认证成功的客户端采集照片 若未找到照片 暂定使用使用首次认证方案
            if (driverFaceRecognitionEntity.getFacePic() == null) {
                String driverName = driverDto.getName();
                String driverIdCareNo = driverDto.getIdCard();
                if (driverName == null || driverIdCareNo == null) {
                    return ResponseData.buildErrorResponse(FACE_RECOGNITION_DRIVER_ERROR.getCode(), FACE_RECOGNITION_DRIVER_ERROR.getMsg());
                }
                //构造binding
                String binding = buildBinding(driverDto);
                String ticketId = StringUtils.buildUUID();
                //获取认证token
                driverFaceRecognitionEntity = FaceRecognitionUtils.rPBioOnly(ticketId, binding);
            } else {
                //获取服务器图片地址前缀
                String faceRetainedPic = SYS_CONFIG.getWebSite() + driverFaceRecognitionEntity.getFacePic();
                //构造bingding参数
                String binding = "{\"FaceRetainedPic\": \"" + faceRetainedPic + "\"}";
                String ticketId = UUID.randomUUID().toString().replaceAll("\\-", "");
                //获取认证token
                driverFaceRecognitionEntity = FaceRecognitionUtils.fVBioOnly(ticketId, binding);
            }
            if (driverFaceRecognitionEntity.getToken() == null) {
                return ResponseData.buildErrorResponse(FACE_RECOGNITION_TOKEN_EXCEPTION.getCode(), FACE_RECOGNITION_TOKEN_EXCEPTION.getMsg());
            }
            //新增认证记录
            driverFaceRecognitionEntity.setMobile(mobile);
            driverFaceRecognitionEntity.setDriverUuid(driverDto.getUuid());
            driverFaceRecognitionMapper.add(driverFaceRecognitionEntity);
        }
        resultMap.put("token", driverFaceRecognitionEntity.getToken());
        resultMap.put("biz", driverFaceRecognitionEntity.getBiz());
        return ResponseData.buildSuccessResponse("获取认证信息成功", resultMap);
    }

    /**
     * 获得人脸识别配置信息
     *
     * @param type
     * @return
     */
    private DriverConfig.CommonBean.FaceRecognitionBean.FaceBean getFaceRecognitionInfo(Integer type) {
        DriverConfig.CommonBean commonBean = ApplicationConfig.DRIVER_CONFIG.getCommon();
        if (commonBean != null) {
            DriverConfig.CommonBean.FaceRecognitionBean faceRecognition = commonBean.getFaceRecognition();
            if (faceRecognition != null) {
                switch (type) {
                    case CommonConstant.BUSINESS_TYPE_TAXI:
                        return faceRecognition.getTaxi();
                    case CommonConstant.BUSINESS_TYPE_SPEC:
                        return faceRecognition.getSpecial();
                    case CommonConstant.BUSINESS_TYPE_POOL:
                        return faceRecognition.getJoin();
                    case CommonConstant.BUSINESS_TYPE_EXPRESS:
                        return faceRecognition.getExpress();
                    default:
                        break;
                }
            }
        }
        return new DriverConfig.CommonBean.FaceRecognitionBean.FaceBean();
    }

    /**
     * 人脸识别校验
     *
     * @param paramMap
     * @return
     */
    @Override
    public ResponseData<DriverFaceRecognitionDto> informResult(Map<String, Object> paramMap) {
        // 还未有认证状态
        paramMap.remove("status");
        DriverFaceRecognitionDto driverFaceRecognitionEntity = driverFaceRecognitionMapper.getNewWestRecode(paramMap);
        if (driverFaceRecognitionEntity != null) {
            //获取认证资料
            driverFaceRecognitionMapper.edit(FaceRecognitionUtils.getMaterials(driverFaceRecognitionEntity));
            return ResponseData.buildSuccessResponse("获取认证资料成功", driverFaceRecognitionEntity);
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取认证信息失败");
    }

    /**
     * 构造人脸识别binding
     */
    private String buildBinding(DriverDto driverDto) {
        //构造bingding参数
        String binding = "\"Name\": \"" + driverDto.getName() + "\",\"IdentificationNumber\": \"" +
                driverDto.getIdCard() + "\"";
        //获取司机身份证照片 若不存在 则不使用该参数
        String idCardFrontPic = driverDto.getIdCardFaceImg();
        String idCardBackPic = driverDto.getIdCardBackImg();
        if (idCardFrontPic != null && idCardBackPic != null) {
            //获取服务器图片地址前缀
            String webSite = SYS_CONFIG.getWebSite();
            binding = binding + ",\"IdCardFrontPic\": \"" + webSite + idCardFrontPic + "\",\"IdCardBackPic\": \"" +
                    webSite + idCardBackPic + "\"";
        }
        binding = "{" + binding + "}";
        return binding;
    }

    /**
     * 通过手机号码查询状态正常的司机
     */
    private DriverDto getDriver(String mobile) {
        Map<String, Object> driverPamaMap = new HashMap<>();
        driverPamaMap.put("mobile", mobile);
        driverPamaMap.put("status", DriverConstant.DRIVER_STATUS_NORMAL);
        List<DriverDto> driverDtoList = driverMapper.list(driverPamaMap);
        if (driverDtoList == null || driverDtoList.size() == 0) {
            return null;
        }
        return driverDtoList.get(0);
    }
}